我想做的是这么一件事:git 每创建一个新分支,push之后自动部署的服务器的不同路径,然后根据不同端口访问不同分支的代码,以方便进行该分支的测试。

并且我正在学习 thinkphp 5 呢,正好测试一下。

举个栗子来说就是:当我新建了一个分支为 8081_opqnext_test,然后完成了某个功能。git add、git commit、当 git push 之后,服务器会自动拉取 8081_opqnext_test 分支上的代码到 /data/tp/8081 这个目录里,然后 访问 beta.tp.opqnext.com:8081 就会直接访问到该分支的代码。同理,当我创建看一个 8082_user_list 的分支。完成了用户列表的功能。git push 之后服务器会自动创建目录 /data/tp/8082 并且将代码到 pull 到该目录。当你访问 beta.tp.opqnext.com:8082 的时候,会访问到该分支的代码便于测试。那 master 的代码每次合并之后 都会自动部署到 /data/tp.opqnext.com/ 访问 tp.opqnext.com 即线上的代码。

然后我们分开步骤来说:

  1. 首先完成自动部署功能。
  2. 各个分支自动部署到不同路径。
  3. 访问不同的端口映射到不同的分支代码。
首先完成自动部署

这里我用的是 码云 git@oschina 来做的。

首先需要配置 ssh公钥,看这里:

特别提醒的是:你的 nginx 是用哪个用户跑的,那么在生产公钥之前先要切换到该用户下。比如我 nginx 是 ngxuser 用户,假如你在 root 下生产公钥并且配置到码云,你的hook是没有权限 clone 和 pull 代码的/(ㄒoㄒ)/~~

你可以按如下命令来生成sshkey:

sudo ngxuser  # 你的nginx用户
ssh-keygen -t rsa -C "xxxxx@xxxxx.com"

# Generating public/private rsa key pair...
# 三次回车即可生成 ssh key

查看你的 public key,并把他添加到码云(Gitee.com)

cat ~/.ssh/id_rsa.pub
# ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQC6eNtGpNGwstc....

添加后,在终端(Terminal)中输入

ssh -T git@git.oschina.net

若返回

Welcome to Git@OSC, yourname!

则说明添加成功,然后去 码云后台 添加你的 ssh key

然后去配置 webhook 查看教程 配置完成 webhook 之后,你每次 push 之后就会触发这个钩子。最简单的,你写一个 auto_deploy_code.php 放到网站根目录。内容是:

<?php
echo '<pre>';
system("git pull", $var);

不用接收 webhook 给你发过来的数据,你只管 pull ,假如你只有一个分支的话。

但是我要接收呢,既然有了数据,当然要接收。

我创建了一个新的分支,这个分支名称可以规定好,比如:8081_opqnext_user (端口-开发者-开发功能)这里怎么约定,那你后面的脚本就怎么写呗。

自动部署的脚本:

<?php
/**
 * GIT webHook 自动部署
 * @author 郭贰小姐
 * @time: 2017/7/13
 */
$hook = str_replace('\"','"',$_POST['hook']);
$res = json_decode($hook,true);
$token = '你配置的token';
if ($res['password'] != $token) {
    error_log('auto_git_pull ['.date('Y-m-d H:i:s').'] token is error]');
} else {
    $dir = '/data/tp/';
    $branch  = explode('/',$res['push_data']['ref'])[2];
    $port = explode('_',$branch)[0];
    $dir = '/data/tp/'.$port;
    if(isset($res['push_data']['commits']) && !empty($res['push_data']['commits'])){
        if($branch == 'master'){
            $cmd = "cd /data/tp.opqnext.com; git pull origin master";
            shell_exec($cmd);
            error_log('auto_git_pull '.$res['push_data']['user_name'].' '.$branch.' msg:'.$res['push_data']['commits'][0]['message'].' =>'.date('H:i:s'));
        } else {
            if(!is_dir($dir)){
                mkdir($dir,0777,true);
                $cmd = "cd $dir; git clone -b $branch git@git.oschina.net:opqnext/thinkphp.git $dir";
            } else {
                $cmd = "cd $dir; git pull origin $branch";
            }
            shell_exec($cmd);
            error_log('auto_git_pull '.$res['push_data']['user_name'].' '.$branch.' msg:'.$res['push_data']['commits'][0]['message'].' =>'.date('H:i:s'));
        }
    } else {
        // 删除分支
        $cmd = "cd /data/tp; rm -rf $port";
        shell_exec($cmd);
        error_log('auto_git_del_branch '.$res['push_data']['user_name'].' '.$branch.' =>'.date('H:i:s'));
    }
}

首先检测 token 是否正确,获取分支名称,截取端口号,填写端口完整路径。
如果 commit 信息有内容,说明判断分支是否为 master 如果是就拉线上代码,如果是分支 commit 检测端口路径是否存在,存在即 pull 否则 clone 没了。

既然各个分支的目录都已经创建好了,代码也可以自动部署了。那再配置 nginx 就可以了,我本来以为可以写一个类似于正则匹配,匹配到哪个端口就去访问对应的路径,但是貌似不行,所以只能写多个 server 监听不同的端口,配置相应的路径。

比如 8081,8082,8083,8084...

每个开发者三五个端口,不错了。大概就是这样一个理论。我发现我写代码从来都是道理基本通,但是不能用...如果你要用的话,再修改修改就 beautiful 了。


已注销
168 声望7 粉丝